const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 提取js中的css为单独文件 
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css文件 
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// eslint检查js语法 
const EslintWebpackPlugin = require('eslint-webpack-plugin')


// 设置node环境变量
process.env.NODE_ENV = 'development' 
// process.env.NODE_ENV = 'production' 

const commonCssLoaders = [
    MiniCssExtractPlugin.loader, 
    'css-loader', 
    {
        loader: 'postcss-loader',
        options: {
            postcssOptions: {
                plugins: [
                    require('postcss-preset-env')()
                ]
            }
        }
    }
]

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/built.[contenthash:10].js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            {
                // 提升性能，避免一个文件被所有loader都过一次，一个文件只被匹配的loader过一次 
                // 注意：不能有两个loader匹配到同一种文件 
                oneOf: [
                    // 处理css资源
                    {
                        test: /\.css$/,
                        use: [...commonCssLoaders]
                    },
                    // 处理less资源 
                    {
                        test: /\.less$/,
                        use: [ ...commonCssLoaders, 'less-loader' ]
                    },
                    // 先执行eslint-loader，再执行babel-loader
                    {
                        test: /\.js$/,
                        exclude: /node_modules/,
                        use: [
                            // 开启多进程打包 
                            {
                                loader: 'thread-loader',
                                options: {
                                    workers: 2  // 进程2个 
                                }
                            },
                            {
                                loader: 'babel-loader',
                                options: {
                                    presets: [
                                        [
                                            '@babel/preset-env',
                                            {
                                                useBuiltIns: 'usage',
                                                corejs: {
                                                    version: 3 
                                                },
                                                targets: {
                                                    chrome: '60',
                                                    firefox: '60',
                                                    ie: '9',
                                                    safari: '10',
                                                    edge: '17'
                                                }
                                            }
                                        ]
                                    ],
                                    // 开启babel缓存，第二次构建时，会读取之前的缓存 
                                    cacheDirectory: true 
                                }
                            }
                        ]
                    },
                    // 处理样式文件中的图片资源
                    {
                        test: /\.(jpg|png|gif)$/,
                        type: 'asset',
                        parser: {
                            dataUrlCondition: {
                                maxSize: 1 * 1024 
                            }
                        },
                        generator: {
                            filename: 'static/imgs/[hash:10].[ext]',
                        }
                    },
                    // 处理html中的图片资源，如img标签引入的图片 
                    {
                        test: /\.html$/,
                        loader: 'html-loader',
                    },
                    // 处理其他资源，file-loader就是将资源文件原封不动地输出出去   
                    {
                        exclude: /\.(html|js|css|less|jpg|png|jif)$/,
                        loader: 'file-loader',
                        options: {
                            filename: 'static/media/[hash:10].[ext]'
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        // eslint 
        new EslintWebpackPlugin({
            extensions: ['js'],
            context: resolve('src'),
            exclude: '/node_modules',
            fix: true // 自动修复不合理写法 
        }), 
        // html处理 
        new HtmlWebpackPlugin({
            template: './src/index.html',
            minify: {
                collapseWhitespace: true,
                removeComments: true 
            } 
        }),
        // 从js中提取css为单独文件 
        new MiniCssExtractPlugin({
            filename: 'css/built.[contenthash:10].css'
        }),
        // 压缩css文件 
        new optimizeCssAssetsWebpackPlugin(),
        
    ],
    // npx webpack-dev-server 
    devServer: {
        static: resolve(__dirname, 'build'),
        compress: true,
        port: 3000,
        open: true, // 自动打开浏览器 
        hot: true // 一个模块更新，只打包这个一模块 
    },
    mode: 'development',
    // 生产环境会自动压缩js代码 
    // mode: 'production' 

    /*
        source-map: 一种 提供源代码到映射后代码 的技术（如果构建后代码出错了，可以通过映射追踪源代码错误） 
        只需要在webpack.config.js中加入 devtool: 'source-map' 即可。
        source-map类型：
            [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map 
            source-map: 外部 
                错误代码准确信息 和 源代码错误位置 
            inline-source-map: 内联，将关联信息放到js文件内，打包速度快；
                只生成一个内联source-map信息，错误代码准确信息 和 源代码错误位置   
            hidden-source-map: 外部，生成一个单独的文件built.js.map存放关联信息 
                错误代码原因，但没有位置，不能追踪到源代码位置 
            eval-source-map: 内联 
                每个文件一个source-map信息 
                有错误代码信息，但没有错误位置 
            nosources-source-map: 外部 
                错误代码准确信息，但没有任何源代码信息
            cheap-source-map: 外部 
                错误代码准确信息 和 源代码错误位置 
            开发环境推荐：
                eval-source-map 
            生产环境推荐：
                source-map 
                cheap-module-source-map


    */
    devtool: 'eval-source-map',
    /*
        externals 拒绝外部依赖被打包到js中，以减少编译后js文件大小 
    */ 
   externals: {
       // 拒绝jQuery被打包进js文件，但需要在index.html中手动引入jQuery 
       jquery: 'jQuery'
   }
}




